Deprecate GtkComboBoxEntry in favor of added properties to GtkComboBox
authorTristan Van Berkom <tristanvb@openismus.com>
Thu, 14 Oct 2010 01:52:27 +0000 (21:52 -0400)
committerMatthias Clasen <mclasen@redhat.com>
Thu, 14 Oct 2010 01:52:27 +0000 (21:52 -0400)
GtkComboBox now sports a construct-only "has-entry" property which
decides if it uses a GtkEntry to allow additional user input. Also
it has a new "entry-text-column" to fetch strings for the entry
from the model.

This patch deprecates the GtkComboBoxEntry and updates the rest of GTK+
to use the new semantics on GtkComboBox instead.

GtkComboBoxEntry will be removed altogether before GTK+ 3, in a
later commit.

15 files changed:
demos/gtk-demo/combobox.c
docs/reference/gtk/gtk3-sections.txt
docs/tools/widgets.c
gtk/gtk.symbols
gtk/gtkcellrenderercombo.c
gtk/gtkcombobox.c
gtk/gtkcombobox.h
gtk/gtkcomboboxentry.c
gtk/gtkcomboboxentry.h
gtk/gtkprinteroptionwidget.c
gtk/tests/builder.c
gtk/tests/object.c
tests/testcombo.c
tests/testgtk.c
tests/testsocket_common.c

index 82588b2923218d7ca379300bef01ba3a1554f029..ff2111b2ff119c15581412181c0701409a1b2f07 100644 (file)
@@ -428,7 +428,14 @@ do_combobox (GtkWidget *do_widget)
     gtk_container_set_border_width (GTK_CONTAINER (box), 5);
     gtk_container_add (GTK_CONTAINER (frame), box);
     
-    combo = gtk_combo_box_entry_new_text ();
+    model = (GtkTreeModel *)gtk_list_store_new (1, G_TYPE_STRING);
+    combo = g_object_new (GTK_TYPE_COMBO_BOX,
+                          "has-entry", TRUE,
+                          "model", model,
+                          "entry-text-column", 0,
+                          NULL);
+    g_object_unref (model);
+
     fill_combo_entry (combo);
     gtk_container_add (GTK_CONTAINER (box), combo);
     
index 0db409b83d10835f680d1de5432b589afe729ecf..c9ebabb4ab72473020a91c379f5e53e102fe282f 100644 (file)
@@ -767,6 +767,7 @@ gtk_color_selection_dialog_get_type
 <TITLE>GtkComboBox</TITLE>
 GtkComboBox
 gtk_combo_box_new
+gtk_combo_box_new_with_entry
 gtk_combo_box_new_with_model
 gtk_combo_box_get_wrap_width
 gtk_combo_box_set_wrap_width
@@ -800,6 +801,9 @@ gtk_combo_box_set_focus_on_click
 gtk_combo_box_get_focus_on_click
 gtk_combo_box_set_button_sensitivity
 gtk_combo_box_get_button_sensitivity
+gtk_combo_box_get_has_entry
+gtk_combo_box_set_entry_text_column
+gtk_combo_box_get_entry_text_column
 <SUBSECTION Standard>
 GTK_TYPE_COMBO_BOX
 GTK_COMBO_BOX
index 45d678c5f0c970bb9cb18c1ecd3d0d4c264ea98f..d5a9901ae5f1f3d4e300b167215e8878369bd5fd 100644 (file)
@@ -282,12 +282,21 @@ create_combo_box_entry (void)
   GtkWidget *widget;
   GtkWidget *align;
   GtkWidget *child;
+  GtkTreeModel *model;
   
   gtk_rc_parse_string ("style \"combo-box-entry-style\" {\n"
                       "  GtkComboBox::appears-as-list = 1\n"
                       "}\n"
                       "widget_class \"GtkComboBoxEntry\" style \"combo-box-entry-style\"\n" );
-  widget = gtk_combo_box_entry_new_text ();
+
+  model = (GtkTreeModel *)gtk_list_store_new (1, G_TYPE_STRING);
+  widget = g_object_new (GTK_TYPE_COMBO_BOX,
+                        "has-entry", TRUE,
+                        "model", model,
+                        "entry-text-column", 0,
+                        NULL);
+  g_object_unref (model);
+
   child = gtk_bin_get_child (GTK_BIN (widget));
   gtk_entry_set_text (GTK_ENTRY (child), "Combo Box Entry");
   align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
index d6215447d56cee7e2a3b8ccc2209cf324cbbad7e..9c29d739b1e60147bff94b53fb14bcc87105ab0f 100644 (file)
@@ -804,7 +804,9 @@ gtk_combo_box_get_active_iter
 gtk_combo_box_get_active_text
 gtk_combo_box_get_add_tearoffs
 gtk_combo_box_get_column_span_column
+gtk_combo_box_get_entry_text_column
 gtk_combo_box_get_focus_on_click
+gtk_combo_box_get_has_entry
 gtk_combo_box_get_model
 gtk_combo_box_get_popup_accessible
 gtk_combo_box_get_row_separator_func
@@ -816,6 +818,7 @@ gtk_combo_box_get_wrap_width
 gtk_combo_box_insert_text
 gtk_combo_box_new
 gtk_combo_box_new_text
+gtk_combo_box_new_with_entry
 gtk_combo_box_new_with_model
 gtk_combo_box_popdown
 gtk_combo_box_popup
@@ -826,6 +829,7 @@ gtk_combo_box_set_active
 gtk_combo_box_set_active_iter
 gtk_combo_box_set_add_tearoffs
 gtk_combo_box_set_column_span_column
+gtk_combo_box_set_entry_text_column
 gtk_combo_box_set_focus_on_click
 gtk_combo_box_set_model
 gtk_combo_box_set_row_separator_func
@@ -838,6 +842,7 @@ gtk_combo_box_set_wrap_width
 
 #if IN_HEADER(__GTK_COMBO_BOX_ENTRY_H__)
 #if IN_FILE(__GTK_COMBO_BOX_ENTRY_C__)
+#ifndef GTK_DISABLE_DEPRECATED
 gtk_combo_box_entry_get_text_column
 gtk_combo_box_entry_get_type G_GNUC_CONST
 gtk_combo_box_entry_new
@@ -846,6 +851,7 @@ gtk_combo_box_entry_new_with_model
 gtk_combo_box_entry_set_text_column
 #endif
 #endif
+#endif
 
 #if IN_HEADER(__GTK_CONTAINER_H__)
 #if IN_FILE(__GTK_CONTAINER_C__)
index 505f2bc6883c4f5038125b1cac407e7d62ea7355..d23521d9844b9e78027e59bc38ac09a3d593cd13 100644 (file)
@@ -27,7 +27,6 @@
 #include "gtkcellrenderercombo.h"
 #include "gtkcellrenderertext.h"
 #include "gtkcombobox.h"
-#include "gtkcomboboxentry.h"
 #include "gtkmarshalers.h"
 #include "gtkprivate.h"
 
@@ -351,7 +350,7 @@ gtk_cell_renderer_combo_editing_done (GtkCellEditable *combo,
       return;
     }
 
-  if (GTK_IS_COMBO_BOX_ENTRY (combo))
+  if (gtk_combo_box_get_has_entry (GTK_COMBO_BOX (combo)))
     {
       entry = GTK_ENTRY (gtk_bin_get_child (GTK_BIN (combo)));
       new_text = g_strdup (gtk_entry_get_text (entry));
@@ -449,11 +448,11 @@ gtk_cell_renderer_combo_start_editing (GtkCellRenderer     *cell,
 
   if (priv->has_entry)
     {
-      combo = gtk_combo_box_entry_new ();
+      combo = g_object_new (GTK_TYPE_COMBO_BOX, "has-entry", TRUE, NULL);
 
       if (priv->model)
         gtk_combo_box_set_model (GTK_COMBO_BOX (combo), priv->model);
-      gtk_combo_box_entry_set_text_column (GTK_COMBO_BOX_ENTRY (combo),
+      gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX (combo),
                                            priv->text_column);
 
       g_object_get (cell_text, "text", &text, NULL);
index aeb5e91a36d135ddc34ebed90f7d6b4511d83dfa..f25ee1257a9ebc5ed719d259777299e75f709444 100644 (file)
@@ -141,6 +141,11 @@ struct _GtkComboBoxPrivate
   gint  minimum_width;
   gint  natural_width;
 
+  /* For "has-entry" specific behavior we track
+   * an automated cell renderer and text column */
+  gint  text_column;
+  GtkCellRenderer *text_renderer;
+
   GSList *cells;
 
   guint popup_in_progress : 1;
@@ -152,6 +157,7 @@ struct _GtkComboBoxPrivate
   guint auto_scroll : 1;
   guint focus_on_click : 1;
   guint button_sensitivity : 2;
+  guint has_entry : 1;
 
   GtkTreeViewRowSeparatorFunc row_separator_func;
   gpointer                    row_separator_data;
@@ -238,7 +244,9 @@ enum {
   PROP_FOCUS_ON_CLICK,
   PROP_POPUP_SHOWN,
   PROP_BUTTON_SENSITIVITY,
-  PROP_EDITING_CANCELED
+  PROP_EDITING_CANCELED,
+  PROP_HAS_ENTRY,
+  PROP_ENTRY_TEXT_COLUMN
 };
 
 static guint combo_box_signals[LAST_SIGNAL] = {0,};
@@ -250,6 +258,9 @@ static guint combo_box_signals[LAST_SIGNAL] = {0,};
 
 static void     gtk_combo_box_cell_layout_init     (GtkCellLayoutIface *iface);
 static void     gtk_combo_box_cell_editable_init   (GtkCellEditableIface *iface);
+static GObject *gtk_combo_box_constructor          (GType                  type,
+                                                   guint                  n_construct_properties,
+                                                   GObjectConstructParam *construct_properties);
 static void     gtk_combo_box_dispose              (GObject          *object);
 static void     gtk_combo_box_finalize             (GObject          *object);
 static void     gtk_combo_box_destroy              (GtkWidget        *widget);
@@ -477,6 +488,13 @@ static void     gtk_combo_box_child_show                     (GtkWidget       *w
 static void     gtk_combo_box_child_hide                     (GtkWidget       *widget,
                                                              GtkComboBox     *combo_box);
 
+/* GtkComboBox:has-entry callbacks */
+static void     gtk_combo_box_entry_contents_changed         (GtkEntry        *entry,
+                                                             gpointer         user_data);
+static void     gtk_combo_box_entry_active_changed           (GtkComboBox     *combo_box,
+                                                             gpointer         user_data);
+
+
 /* GtkBuildable method implementation */
 static GtkBuildableIface *parent_buildable_iface;
 
@@ -492,6 +510,10 @@ static void     gtk_combo_box_buildable_custom_tag_end       (GtkBuildable  *bui
                                                              GObject       *child,
                                                              const gchar   *tagname,
                                                              gpointer      *data);
+static GObject *gtk_combo_box_buildable_get_internal_child   (GtkBuildable *buildable,
+                                                             GtkBuilder   *builder,
+                                                             const gchar  *childname);
+
 
 /* GtkCellEditable method implementations */
 static void     gtk_combo_box_start_editing                  (GtkCellEditable *cell_editable,
@@ -553,6 +575,7 @@ gtk_combo_box_class_init (GtkComboBoxClass *klass)
   widget_class->destroy = gtk_combo_box_destroy;
 
   object_class = (GObjectClass *)klass;
+  object_class->constructor = gtk_combo_box_constructor;
   object_class->dispose = gtk_combo_box_dispose;
   object_class->finalize = gtk_combo_box_finalize;
   object_class->set_property = gtk_combo_box_set_property;
@@ -896,6 +919,39 @@ gtk_combo_box_class_init (GtkComboBoxClass *klass)
                                                        GTK_SENSITIVITY_AUTO,
                                                        GTK_PARAM_READWRITE));
 
+   /**
+    * GtkComboBox:has-entry:
+    *
+    * Whether the combo box has an entry.
+    *
+    * Since: 3.0
+    */
+   g_object_class_install_property (object_class,
+                                    PROP_HAS_ENTRY,
+                                    g_param_spec_boolean ("has-entry",
+                                                         P_("Has Entry"),
+                                                         P_("Whether combo box has an entry"),
+                                                         FALSE,
+                                                         GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+   /**
+    * GtkComboBox:entry-text-column:
+    *
+    * The column in the combo box's model to associate with strings from the entry
+    * if the combo was created with #GtkComboBox:has-entry = %TRUE.
+    *
+    * Since: 3.0
+    */
+   g_object_class_install_property (object_class,
+                                    PROP_ENTRY_TEXT_COLUMN,
+                                    g_param_spec_int ("entry-text-column",
+                                                     P_("Entry Text Column"),
+                                                     P_("The column in the combo box's model to associate "
+                                                        "with strings from the entry if the combo was "
+                                                        "created with #GtkComboBox:has-entry = %TRUE"),
+                                                     -1, G_MAXINT, -1,
+                                                     GTK_PARAM_READWRITE));
+
   gtk_widget_class_install_style_property (widget_class,
                                            g_param_spec_boolean ("appears-as-list",
                                                                  P_("Appears as list"),
@@ -947,6 +1003,7 @@ gtk_combo_box_buildable_init (GtkBuildableIface *iface)
   iface->add_child = _gtk_cell_layout_buildable_add_child;
   iface->custom_tag_start = gtk_combo_box_buildable_custom_tag_start;
   iface->custom_tag_end = gtk_combo_box_buildable_custom_tag_end;
+  iface->get_internal_child = gtk_combo_box_buildable_get_internal_child;
 }
 
 static void
@@ -1001,6 +1058,10 @@ gtk_combo_box_init (GtkComboBox *combo_box)
   priv->auto_scroll = FALSE;
   priv->focus_on_click = TRUE;
   priv->button_sensitivity = GTK_SENSITIVITY_AUTO;
+  priv->has_entry = FALSE;
+
+  priv->text_column = -1;
+  priv->text_renderer = NULL;
 
   gtk_combo_box_check_appearance (combo_box);
 }
@@ -1041,6 +1102,17 @@ gtk_combo_box_set_property (GObject      *object,
 
     case PROP_HAS_FRAME:
       combo_box->priv->has_frame = g_value_get_boolean (value);
+
+      if (combo_box->priv->has_entry)
+        {
+          GtkWidget *child;
+
+          child = gtk_bin_get_child (GTK_BIN (combo_box));
+
+          gtk_entry_set_has_frame (GTK_ENTRY (child),
+                                   combo_box->priv->has_frame);
+        }
+
       break;
 
     case PROP_FOCUS_ON_CLICK:
@@ -1068,6 +1140,14 @@ gtk_combo_box_set_property (GObject      *object,
       combo_box->priv->editing_canceled = g_value_get_boolean (value);
       break;
 
+    case PROP_HAS_ENTRY:
+      combo_box->priv->has_entry = g_value_get_boolean (value);
+      break;
+
+    case PROP_ENTRY_TEXT_COLUMN:
+      gtk_combo_box_set_entry_text_column (combo_box, g_value_get_int (value));
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -1133,6 +1213,13 @@ gtk_combo_box_get_property (GObject    *object,
         g_value_set_boolean (value, priv->editing_canceled);
         break;
 
+      case PROP_HAS_ENTRY:
+       g_value_set_boolean (value, priv->has_entry);
+       break;
+
+      case PROP_ENTRY_TEXT_COLUMN:
+       g_value_set_int (value, priv->text_column);
+       break;
       default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
         break;
@@ -1265,6 +1352,14 @@ gtk_combo_box_add (GtkContainer *container,
   GtkComboBox *combo_box = GTK_COMBO_BOX (container);
   GtkComboBoxPrivate *priv = combo_box->priv;
 
+  if (priv->has_entry && !GTK_IS_ENTRY (widget))
+    {
+      g_warning ("Attempting to add a widget with type %s to a GtkComboBox that needs an entry "
+                "(need an instance of GtkEntry or of a subclass)",
+                 G_OBJECT_TYPE_NAME (widget));
+      return;
+    }
+
   if (priv->cell_view &&
       gtk_widget_get_parent (priv->cell_view))
     {
@@ -1297,6 +1392,19 @@ gtk_combo_box_add (GtkContainer *container,
           priv->box = NULL;
         }
     }
+
+  if (priv->has_entry)
+    {
+      /* this flag is a hack to tell the entry to fill its allocation.
+       */
+      GTK_ENTRY (widget)->is_cell_renderer = TRUE;
+
+      g_signal_connect (widget, "changed",
+                       G_CALLBACK (gtk_combo_box_entry_contents_changed),
+                       combo_box);
+
+      gtk_entry_set_has_frame (GTK_ENTRY (widget), priv->has_frame);
+    }
 }
 
 static void
@@ -1308,6 +1416,20 @@ gtk_combo_box_remove (GtkContainer *container,
   GtkTreePath *path;
   gboolean appears_as_list;
 
+  if (priv->has_entry)
+    {
+      GtkWidget *child_widget;
+
+      child_widget = gtk_bin_get_child (GTK_BIN (container));
+      if (widget && widget == child_widget)
+       {
+         g_signal_handlers_disconnect_by_func (widget,
+                                               gtk_combo_box_entry_contents_changed,
+                                               container);
+         GTK_ENTRY (widget)->is_cell_renderer = FALSE;
+       }
+    }
+
   if (widget == priv->cell_view)
     priv->cell_view = NULL;
 
@@ -4653,6 +4775,19 @@ gtk_combo_box_new (void)
   return g_object_new (GTK_TYPE_COMBO_BOX, NULL);
 }
 
+/**
+ * gtk_combo_box_new_with_entry:
+ *
+ * Creates a new empty #GtkComboBox with an entry.
+ *
+ * Return value: A new #GtkComboBox.
+ */
+GtkWidget *
+gtk_combo_box_new_with_entry (void)
+{
+  return g_object_new (GTK_TYPE_COMBO_BOX, "has-entry", TRUE, NULL);
+}
+
 /**
  * gtk_combo_box_new_with_model:
  * @model: A #GtkTreeModel.
@@ -5333,15 +5468,29 @@ gtk_combo_box_real_get_active_text (GtkComboBox *combo_box)
   GtkTreeIter iter;
   gchar *text = NULL;
 
-  g_return_val_if_fail (GTK_IS_LIST_STORE (combo_box->priv->model), NULL);
-  g_return_val_if_fail (gtk_tree_model_get_column_type (combo_box->priv->model, 0)
-                        == G_TYPE_STRING, NULL);
+  if (combo_box->priv->has_entry)
+    {
+      GtkBin *combo = GTK_BIN (combo_box);
+      GtkWidget *child;
+
+      child = gtk_bin_get_child (combo);
+      if (child)
+       return g_strdup (gtk_entry_get_text (GTK_ENTRY (child)));
 
-  if (gtk_combo_box_get_active_iter (combo_box, &iter))
-    gtk_tree_model_get (combo_box->priv->model, &iter, 
-                       0, &text, -1);
+      return NULL;
+    }
+  else
+    {
+      g_return_val_if_fail (GTK_IS_LIST_STORE (combo_box->priv->model), NULL);
+      g_return_val_if_fail (gtk_tree_model_get_column_type (combo_box->priv->model, 0)
+                           == G_TYPE_STRING, NULL);
 
-  return text;
+      if (gtk_combo_box_get_active_iter (combo_box, &iter))
+        gtk_tree_model_get (combo_box->priv->model, &iter,
+                           0, &text, -1);
+
+      return text;
+    }
 }
 
 static void
@@ -5434,7 +5583,16 @@ gtk_combo_box_mnemonic_activate (GtkWidget *widget,
 {
   GtkComboBox *combo_box = GTK_COMBO_BOX (widget);
 
-  gtk_widget_grab_focus (combo_box->priv->button);
+  if (combo_box->priv->has_entry)
+    {
+      GtkWidget* child;
+
+      child = gtk_bin_get_child (GTK_BIN (combo_box));
+      if (child)
+       gtk_widget_grab_focus (child);
+    }
+  else
+    gtk_widget_grab_focus (combo_box->priv->button);
 
   return TRUE;
 }
@@ -5444,7 +5602,16 @@ gtk_combo_box_grab_focus (GtkWidget *widget)
 {
   GtkComboBox *combo_box = GTK_COMBO_BOX (widget);
 
-  gtk_widget_grab_focus (combo_box->priv->button);
+  if (combo_box->priv->has_entry)
+    {
+      GtkWidget *child;
+
+      child = gtk_bin_get_child (GTK_BIN (combo_box));
+      if (child)
+       gtk_widget_grab_focus (child);
+    }
+  else
+    gtk_widget_grab_focus (combo_box->priv->button);
 }
 
 static void
@@ -5471,6 +5638,94 @@ gtk_combo_box_destroy (GtkWidget *widget)
   combo_box->priv->cell_view = NULL;
 }
 
+static void
+gtk_combo_box_entry_contents_changed (GtkEntry *entry,
+                                      gpointer  user_data)
+{
+  GtkComboBox *combo_box = GTK_COMBO_BOX (user_data);
+
+  /*
+   *  Fixes regression reported in bug #574059. The old functionality relied on
+   *  bug #572478.  As a bugfix, we now emit the "changed" signal ourselves
+   *  when the selection was already set to -1.
+   */
+  if (gtk_combo_box_get_active(combo_box) == -1)
+    g_signal_emit_by_name (combo_box, "changed");
+  else
+    gtk_combo_box_set_active (combo_box, -1);
+}
+
+static void
+gtk_combo_box_entry_active_changed (GtkComboBox *combo_box,
+                                    gpointer     user_data)
+{
+  GtkComboBoxPrivate *priv = combo_box->priv;
+  GtkTreeModel *model;
+  GtkTreeIter iter;
+  gchar *str = NULL;
+
+  if (gtk_combo_box_get_active_iter (combo_box, &iter))
+    {
+      GtkEntry *entry = GTK_ENTRY (gtk_bin_get_child (GTK_BIN (combo_box)));
+
+      if (entry)
+       {
+         g_signal_handlers_block_by_func (entry,
+                                          gtk_combo_box_entry_contents_changed,
+                                          combo_box);
+
+         model = gtk_combo_box_get_model (combo_box);
+
+         gtk_tree_model_get (model, &iter,
+                             priv->text_column, &str,
+                             -1);
+         gtk_entry_set_text (entry, str);
+         g_free (str);
+
+         g_signal_handlers_unblock_by_func (entry,
+                                            gtk_combo_box_entry_contents_changed,
+                                            combo_box);
+       }
+    }
+}
+
+static GObject *
+gtk_combo_box_constructor (GType                  type,
+                          guint                  n_construct_properties,
+                          GObjectConstructParam *construct_properties)
+{
+  GObject            *object;
+  GtkComboBox        *combo_box;
+  GtkComboBoxPrivate *priv;
+
+  object = G_OBJECT_CLASS (gtk_combo_box_parent_class)->constructor
+    (type, n_construct_properties, construct_properties);
+
+  combo_box = GTK_COMBO_BOX (object);
+  priv      = combo_box->priv;
+
+  if (priv->has_entry)
+    {
+      GtkWidget *entry;
+
+      entry = gtk_entry_new ();
+      gtk_widget_show (entry);
+      gtk_container_add (GTK_CONTAINER (combo_box), entry);
+
+      priv->text_renderer = gtk_cell_renderer_text_new ();
+      gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box),
+                                 priv->text_renderer, TRUE);
+
+      gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), -1);
+
+      g_signal_connect (combo_box, "changed",
+                       G_CALLBACK (gtk_combo_box_entry_active_changed), NULL);
+    }
+
+  return object;
+}
+
+
 static void
 gtk_combo_box_dispose(GObject* object)
 {
@@ -5525,6 +5780,7 @@ gtk_combo_box_finalize (GObject *object)
    G_OBJECT_CLASS (gtk_combo_box_parent_class)->finalize (object);
 }
 
+
 static gboolean
 gtk_cell_editable_key_press (GtkWidget   *widget,
                             GdkEventKey *event,
@@ -5892,6 +6148,77 @@ gtk_combo_box_get_button_sensitivity (GtkComboBox *combo_box)
 }
 
 
+/**
+ * gtk_combo_box_get_has_entry:
+ * @combo_box: a #GtkComboBox
+ *
+ * Returns whether the combo box has an entry.
+ *
+ * Return Value: whether there is an entry in @combo_box.
+ *
+ * Since: 3.0
+ **/
+gboolean
+gtk_combo_box_get_has_entry (GtkComboBox *combo_box)
+{
+  g_return_val_if_fail (GTK_IS_COMBO_BOX (combo_box), FALSE);
+
+  return combo_box->priv->has_entry;
+}
+
+/**
+ * gtk_combo_box_set_entry_text_column:
+ * @combo_box: A #GtkComboBox.
+ * @text_column: A column in @model to get the strings from for the internal entry.
+ *
+ * Sets the model column which @combo_box should use to get strings from
+ * to be @text_column.
+ *
+ * @combo_box must be created with GtkComboBox:has-entry as %TRUE.
+ *
+ * Since: 3.0
+ */
+void
+gtk_combo_box_set_entry_text_column (GtkComboBox *combo_box,
+                                    gint         text_column)
+{
+  GtkTreeModel *model;
+
+  g_return_if_fail (GTK_IS_COMBO_BOX (combo_box));
+  g_return_if_fail (combo_box->priv->has_entry != FALSE);
+
+  model = gtk_combo_box_get_model (combo_box);
+
+  g_return_if_fail (text_column >= 0);
+  g_return_if_fail (model == NULL || text_column < gtk_tree_model_get_n_columns (model));
+
+  combo_box->priv->text_column = text_column;
+
+  gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box),
+                                  combo_box->priv->text_renderer,
+                                  "text", text_column,
+                                  NULL);
+}
+
+/**
+ * gtk_combo_box_get_entry_text_column:
+ * @combo_box: A #GtkComboBox.
+ *
+ * Returns the column which @combo_box is using to get the strings
+ * from to display in the internal entry.
+ *
+ * Return value: A column in the data source model of @combo_box.
+ *
+ * Since: 3.0
+ */
+gint
+gtk_combo_box_get_entry_text_column (GtkComboBox *combo_box)
+{
+  g_return_val_if_fail (GTK_IS_COMBO_BOX (combo_box), 0);
+
+  return combo_box->priv->text_column;
+}
+
 /**
  * gtk_combo_box_set_focus_on_click:
  * @combo: a #GtkComboBox
@@ -5977,6 +6304,18 @@ gtk_combo_box_buildable_custom_tag_end (GtkBuildable *buildable,
                                            data);
 }
 
+static GObject *
+gtk_combo_box_buildable_get_internal_child (GtkBuildable *buildable,
+                                           GtkBuilder   *builder,
+                                           const gchar  *childname)
+{
+  GtkComboBox *combo_box = GTK_COMBO_BOX (buildable);
+
+  if (combo_box->priv->has_entry && strcmp (childname, "entry") == 0)
+    return G_OBJECT (gtk_bin_get_child (GTK_BIN (buildable)));
+
+  return parent_buildable_iface->get_internal_child (buildable, builder, childname);
+}
 
 static void
 gtk_combo_box_remeasure (GtkComboBox *combo_box)
index 84f54755b54bb0c9ce568b696f023b81a7e827b2..0ece10f7dae3daa68856783f75ab8afa5320b72e 100644 (file)
@@ -69,6 +69,7 @@ struct _GtkComboBoxClass
 /* construction */
 GType         gtk_combo_box_get_type         (void) G_GNUC_CONST;
 GtkWidget    *gtk_combo_box_new              (void);
+GtkWidget    *gtk_combo_box_new_with_entry   (void);
 GtkWidget    *gtk_combo_box_new_with_model   (GtkTreeModel    *model);
 
 /* grids */
@@ -118,6 +119,11 @@ void               gtk_combo_box_set_button_sensitivity (GtkComboBox        *com
                                                         GtkSensitivityType  sensitivity);
 GtkSensitivityType gtk_combo_box_get_button_sensitivity (GtkComboBox        *combo_box);
 
+gboolean           gtk_combo_box_get_has_entry          (GtkComboBox        *combo_box);
+void               gtk_combo_box_set_entry_text_column  (GtkComboBox        *combo_box,
+                                                        gint                text_column);
+gint               gtk_combo_box_get_entry_text_column  (GtkComboBox        *combo_box);
+
 /* convenience -- text */
 GtkWidget    *gtk_combo_box_new_text         (void);
 void          gtk_combo_box_append_text      (GtkComboBox     *combo_box,
index dfea2ae50e5aee1ab5f89ad8f275f80222e44421..f538c7274d02af3aec735393118d9e5f52f0cc42 100644 (file)
@@ -19,6 +19,9 @@
 
 #include "config.h"
 #include <string.h>
+
+#undef GTK_DISABLE_DEPRECATED
+
 #include "gtkcomboboxentry.h"
 #include "gtkcelllayout.h"
 
@@ -363,6 +366,8 @@ gtk_combo_box_entry_contents_changed (GtkEntry *entry,
  * Return value: A new #GtkComboBoxEntry.
  *
  * Since: 2.4
+ *
+ * Deprecated: 2.24: Use gtk_combo_box_new_with_entry() instead
  */
 GtkWidget *
 gtk_combo_box_entry_new (void)
@@ -384,6 +389,8 @@ gtk_combo_box_entry_new (void)
  * Return value: A new #GtkComboBoxEntry.
  *
  * Since: 2.4
+ *
+ * Deprecated: 2.24: Use gtk_combo_box_new_with_entry() instead
  */
 GtkWidget *
 gtk_combo_box_entry_new_with_model (GtkTreeModel *model,
@@ -412,6 +419,8 @@ gtk_combo_box_entry_new_with_model (GtkTreeModel *model,
  * to be @text_column.
  *
  * Since: 2.4
+ *
+ * Deprecated: 2.24: Use gtk_combo_box_set_entry_text_column() instead
  */
 void
 gtk_combo_box_entry_set_text_column (GtkComboBoxEntry *entry_box,
@@ -439,6 +448,8 @@ gtk_combo_box_entry_set_text_column (GtkComboBoxEntry *entry_box,
  * Return value: A column in the data source model of @entry_box.
  *
  * Since: 2.4
+ *
+ * Deprecated: 2.24: Use gtk_combo_box_get_entry_text_column() instead
  */
 gint
 gtk_combo_box_entry_get_text_column (GtkComboBoxEntry *entry_box)
index 5c6168d938753fb7f8f7da81ef053bf161d6b277..ed289e57dfc6b856ddd0e2b56661b831c164de6f 100644 (file)
@@ -29,6 +29,8 @@
 
 G_BEGIN_DECLS
 
+#ifndef GTK_DISABLE_DEPRECATED
+
 #define GTK_TYPE_COMBO_BOX_ENTRY             (gtk_combo_box_entry_get_type ())
 #define GTK_COMBO_BOX_ENTRY(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_COMBO_BOX_ENTRY, GtkComboBoxEntry))
 #define GTK_COMBO_BOX_ENTRY_CLASS(vtable)    (G_TYPE_CHECK_CLASS_CAST ((vtable), GTK_TYPE_COMBO_BOX_ENTRY, GtkComboBoxEntryClass))
@@ -72,6 +74,7 @@ gint        gtk_combo_box_entry_get_text_column (GtkComboBoxEntry *entry_box);
 /* convenience -- text */
 GtkWidget  *gtk_combo_box_entry_new_text        (void);
 
+#endif
 
 G_END_DECLS
 
index 8831dfc0925d92afd7f62950774f43c327b00962..8349d2c8bb3e7e7d8e95b177d9922061de66abde 100644 (file)
@@ -29,7 +29,6 @@
 #include "gtkcelllayout.h"
 #include "gtkcellrenderertext.h"
 #include "gtkcombobox.h"
-#include "gtkcomboboxentry.h"
 #include "gtkfilechooserbutton.h"
 #include "gtkimage.h"
 #include "gtklabel.h"
@@ -287,11 +286,11 @@ static GtkWidget *
 combo_box_entry_new (void)
 {
   GtkWidget *combo_box;
-  combo_box = gtk_combo_box_entry_new ();
+  combo_box = g_object_new (GTK_TYPE_COMBO_BOX, "has-entry", TRUE, NULL);
 
   combo_box_set_model (combo_box);
 
-  gtk_combo_box_entry_set_text_column (GTK_COMBO_BOX_ENTRY (combo_box), NAME_COLUMN);
+  gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX (combo_box), NAME_COLUMN);
 
   return combo_box;
 }
@@ -373,7 +372,7 @@ combo_box_get (GtkWidget *combo)
   gchar *value;
   GtkTreeIter iter;
 
-  if (GTK_IS_COMBO_BOX_ENTRY (combo))
+  if (gtk_combo_box_get_has_entry (GTK_COMBO_BOX (combo)))
     {
       value = gtk_combo_box_get_active_text(GTK_COMBO_BOX (combo));
     }
index 0a3f62539aa84c770cfde2a5a46024367c84c658..b9ad395c5786a3c61779f6bce1f7f345ce449c0a 100644 (file)
@@ -1336,8 +1336,9 @@ test_combo_box_entry (void)
     "  </object>"
     "  <object class=\"GtkWindow\" id=\"window1\">"
     "    <child>"
-    "      <object class=\"GtkComboBoxEntry\" id=\"comboboxentry1\">"
+    "      <object class=\"GtkComboBox\" id=\"comboboxentry1\">"
     "        <property name=\"model\">liststore1</property>"
+    "        <property name=\"has-entry\">True</property>"
     "        <property name=\"visible\">True</property>"
     "        <child>"
     "          <object class=\"GtkCellRendererText\" id=\"renderer1\"/>"
index feb724adadcc6399b8ca8c7b22edc3d2d0fd89b9..4a38f005fee92b9d11623f27f78a55a9e3333dd8 100644 (file)
@@ -72,7 +72,6 @@ list_ignore_properties (gboolean buglist)
     { "GtkColorSelection",      "current-color",        (void*) NULL, },                /* not a valid boxed color */
     { "GtkComboBox",            "row-span-column",      (void*) MATCH_ANY_VALUE },      /* GtkComboBoxEntry needs a tree model for this */
     { "GtkComboBox",            "column-span-column",   (void*) MATCH_ANY_VALUE },      /* GtkComboBoxEntry needs a tree model for this */
-    { "GtkComboBoxEntry",       "text-column",          (void*) MATCH_ANY_VALUE },      /* GtkComboBoxEntry needs a tree model for this */
     { "GtkFileChooserButton",   "select-multiple",      (void*) MATCH_ANY_VALUE },      /* property disabled */
     { "GtkFileChooserButton",   "action",               (void*) GTK_FILE_CHOOSER_ACTION_SAVE },
     { "GtkFileChooserButton",   "action",               (void*) GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER },
@@ -279,14 +278,7 @@ static void
 widget_fixups (GtkWidget *widget)
 {
   /* post-constructor for widgets that need additional settings to work correctly */
-  if (GTK_IS_COMBO_BOX_ENTRY (widget))
-    {
-      GtkListStore *store = gtk_list_store_new (1, G_TYPE_STRING);
-      g_object_set (widget, "model", store, "text-column", 0, NULL);
-      g_object_unref (store);
-      gtk_combo_box_append_text (GTK_COMBO_BOX (widget), "test text");
-    }
-  else if (GTK_IS_COMBO_BOX (widget))
+  if (GTK_IS_COMBO_BOX (widget))
     {
       GtkListStore *store = gtk_list_store_new (1, G_TYPE_STRING);
       g_object_set (widget, "model", store, NULL);
index bf01142925186040eb16c4ee09e32178055a7e64..9e0fc40548dea6c54410829d8986d48a1af26d59 100644 (file)
@@ -1021,7 +1021,8 @@ main (int argc, char **argv)
        GtkTreePath *path;
        GtkTreeIter iter;
         GdkColor color;
-       
+       GtkListStore *store;
+
         gtk_init (&argc, &argv);
 
        if (g_getenv ("RTL"))
@@ -1265,14 +1266,21 @@ main (int argc, char **argv)
 
 
         /* GtkComboBoxEntry */
-        tmp = gtk_frame_new ("GtkComboBoxEntry");
+        tmp = gtk_frame_new ("GtkComboBox with entry");
         gtk_box_pack_start (GTK_BOX (mainbox), tmp, FALSE, FALSE, 0);
 
         boom = gtk_vbox_new (FALSE, 0);
         gtk_container_set_border_width (GTK_CONTAINER (boom), 5);
         gtk_container_add (GTK_CONTAINER (tmp), boom);
 
-        comboboxtext = gtk_combo_box_entry_new_text ();
+       store = gtk_list_store_new (1, G_TYPE_STRING);
+        comboboxtext = g_object_new (GTK_TYPE_COMBO_BOX,
+                                    "has-entry", TRUE,
+                                    "model", store,
+                                    "entry-text-column", 0,
+                                    NULL);
+       g_object_unref (store);
+
        setup_combo_entry (comboboxtext);
         gtk_container_add (GTK_CONTAINER (boom), comboboxtext);
 
index 17136cfc57b160d24bd01dd2a0beb17833572daf..b741023f5299a22344ab2c42258b738f795f5abc 100644 (file)
@@ -3955,6 +3955,7 @@ create_entry (GtkWidget *widget)
   GtkWidget *cb_entry;
   GtkWidget *button;
   GtkWidget *separator;
+  GtkListStore *store;
 
   if (!window)
     {
@@ -3992,7 +3993,14 @@ create_entry (GtkWidget *widget)
                        G_CALLBACK (props_clicked),
                        entry);
 
-      cb = GTK_COMBO_BOX (gtk_combo_box_entry_new_text ());
+      store = gtk_list_store_new (1, G_TYPE_STRING);
+      cb = g_object_new (GTK_TYPE_COMBO_BOX,
+                        "has-entry", TRUE,
+                        "model", store,
+                        "entry-text-column", 0,
+                        NULL);
+      g_object_unref (store);
+
       gtk_combo_box_append_text (cb, "item0");
       gtk_combo_box_append_text (cb, "item0");
       gtk_combo_box_append_text (cb, "item1 item1");
index da28f3a81c8b84602767d27ffad61e9e8dd18aed..78eb7d55ca60dcee72202c3e52c823d499df07de 100644 (file)
@@ -134,8 +134,16 @@ create_combo (void)
 {
   GtkComboBox *combo;
   GtkWidget *entry;
+  GtkListStore *store;
+
+  store = gtk_list_store_new (1, G_TYPE_STRING);
+  combo = g_object_new (GTK_TYPE_COMBO_BOX,
+                       "has-entry", TRUE,
+                       "model", store,
+                       "entry-text-column", 0,
+                       NULL);
+  g_object_unref (store);
 
-  combo = GTK_COMBO_BOX (gtk_combo_box_entry_new_text ());
   gtk_combo_box_append_text (combo, "item0");
   gtk_combo_box_append_text (combo, "item1 item1");
   gtk_combo_box_append_text (combo, "item2 item2 item2");